import { AudioClip, Node, Prefab, Vec2, Vec3, v2 } from 'cc';
import { EventName } from '../consts/events';
import { EventManager } from './events/events';
import { EventHandler } from './events/types';
import { loadBundle } from './assets/bundle';
import { loadResource } from './assets/resources';
import { LocalStore } from './store/LocalStore';
import { ObjectPool } from './store/ObjectPool';
import { cloneDeep } from './tools/data';
import { generateRandomString, upperFirstLetter } from './tools/strings';
import { System } from './tools/system';
import { UUID } from './tools/uuid';
import { Uni } from './uni';
import { AudioManager } from './assets/audio';
import { AnimationTools } from './assets/animation';

class Utils {
    // ---------------------工具--------------------
    public static tools = {
        loadBundle: loadBundle, // 动态资源加载
        loadResource: loadResource, // 加载resource目录下的资源
        cloneDeep: cloneDeep, // 深拷贝
        genUUID: (): number => {
            return UUID.instance.genID();
        },
        genRandString: (): string => {
            return UUID.instance.genRandString();
        },
        toV2(pos: Vec3): Vec2 {
            return v2(pos.x, pos.y);
        },
        upperFirstLetter: upperFirstLetter,
        generateRandomString: generateRandomString
    };

    // ---------------------事件--------------------
    public static events = {
        emit: (eventName: EventName, data: string | number | object = {}) => {
            EventManager.instance.emitEvent(eventName, data);
        },
        on: (eventName: EventName, callback: EventHandler, self: object) => {
            return EventManager.instance.addListener(eventName, callback, self);
        },
        off: (eventName: EventName, callback: EventHandler, self: object) => {
            return EventManager.instance.removeListener(eventName, callback, self);
        }
    };

    // ---------------------存储--------------------
    public static store = {
        getLocalStore: <T>(key: string): T => {
            return LocalStore.instance.getByKey<T>(key);
        },
        setLocalStore: (key: string, value: any) => {
            LocalStore.instance.setByKey(key, value);
        },
        loadLocalStore: (key: string) => {
            LocalStore.instance.load(key);
        }
    };
    // #endregion

    // ---------------------对象池--------------------
    public static pool = {
        createNode: (prefab: Prefab): Node => {
            return ObjectPool.instance.createNode(prefab); // 对象池：创建对象
        },
        returnNode: (node: Node) => {
            ObjectPool.instance.returnNode(node); // 对象池：归还对象
        }
    };

    public static audio = {
        play: (sound: AudioClip | string, loop: boolean = false, volume: number = 1.0) => {
            AudioManager.instance.play(sound, loop, volume);
        },
        stop: () => {
            AudioManager.instance.stop();
        },
        pause: () => {
            AudioManager.instance.pause();
        },
        resume: () => {
            AudioManager.instance.resume();
        },
        playOneShot: (sound: AudioClip | string, volume: number = 1.0) => {
            AudioManager.instance.playOneShot(sound, volume);
        }
    };

    public static animation = AnimationTools.instance;
    public static uni = Uni.instance;
    public static sys = System.instance;
}

export default Utils;
